#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<sstream>
#include<assert.h>
#include<cmath>
#include<vector>
#include<string>
#include<map>
#include<set>
#include<queue>
#include<stack>
using namespace std;
typedef long long ll;
const int inf=1000000000;
const double pi=acos(-1.0);
#define eps (1e-15)
#define L (nod)<<1
#define R (nod)<<1|1
#define lson nod<<1,l,mid
#define rson nod<<1|1,mid+1,r
#define clr(x,a) memset(x,a,sizeof(x))
#define see(x)(cerr<<"[line:"<<__LINE__<<" "<<#x<<" "<<x<<endl)
#define se(x) cerr<<x<<" "
#define sz(x) (int)x.size()
#define pb push_back
template<class T>void show(T a, int n){for(int i=0; i<n; ++i) cout<<a[i]<<' '; cout<<endl;}
template<class T>void show(T a, int r, int l){for(int i=0; i<r; ++i)show(a[i],l);cout<<endl;}

inline int to_i(const string& s)
{int n;sscanf(s.c_str(),"%d",&n);return n;}
inline string to_s(int n)
{char buf[32];sprintf(buf,"%d",n);return string(buf);}
inline int rd(){int x;scanf("%d",&x);return x;}
const int maxn = 70000;
const int maxe =110000;
int n,m;
int nodeval[maxn],first[maxn],next[maxe],E[maxe],M;
void init()
{
	M=-1;
	clr(first,-1);
}
void _ins(int a,int b)
{
	M++;
	next[M]=first[a];
	first[a]=M;
	E[M]=b;
}
void ins(int a,int b)
{
	_ins(a,b);_ins(b,a);
}

struct node
{
	int a,add;
}qtr[maxn*4],*tl,*head[maxn];
int trsz[maxn],cas,dep[maxn],belong[maxn],pos[maxn],vis[maxn],son[maxn];
int rmq[maxn][20],LOG=18;

void pushdown(node *tr,int nod)
{
	if(tr[nod].add)
	{
		tr[R].add+=tr[nod].add;
		tr[L].add+=tr[nod].add;
		tr[L].a+=tr[nod].add;
		tr[R].a+=tr[nod].add;
		tr[nod].add=0;
	}
}
void insert(node *tr,int nod,int l,int r,int x,int y,int a)
{//把值x到y的值改成a
	if(l==r)
	{
		tr[nod].a=a;
		return ;
	}
	pushdown(tr,nod);
	int mid=(l+r)/2;
	if(x<=mid)
		insert(tr,lson,x,y,a);
	if(mid<y)
		insert(tr,rson,x,y,a);
}
void maketree(int u,int h)
{
	int i,rt=u;
	for(i=1; i<h; i++)	rt=rmq[rt][0];/找到根 
	head[rt]=tl;
	for(i=0; i<h*4; i++)//初始话树
		head[rt][i].a=head[rt][i].add=0;
		
	tl+=h*4;//偏移量加值
	trsz[rt]=h;//记录这颗树有多少个元素
	for(i=h; i>=1; i--)
	{
		belong[u]=rt;//当前节点属于那棵树
		pos[u]=i;//当前节点所在的这颗树第几个元素
		insert(head[rt],1,1,h,i,i,nodeval[u]);
		u=rmq[u][0];
	}
}

void update(node*tr,int nod,int l,int r,int x,int y,int a)
{//更新对某些树的点加上某一值
	if(x<=l && r<=y)
	{
		tr[nod].add+=a;
		tr[nod].a+=a;
		return ;
	}
	pushdown(tr,nod);
	int mid=(l+r)/2;
	if(x<=mid)
		update(tr,lson,x,y,a);
	if(mid<y)
		update(tr,rson,x,y,a);
}

int getupdate(int a,int b,int z)//更新对某些树的点加上某一值
{
	int i,fa,fb,ret=0;
	while(a!=b)
	{
		fa=belong[a],fb=belong[b];
		if(fa!=fb)
		{
			update(head[fb],1,1,trsz[fb],1,pos[b],z);
			b=rmq[fb][0];
		}
		else
		{
			ret=1;
		update(head[fb],1,1,trsz[fb],pos[a],pos[b],z);
			break;
		}
	}
	return ret;
}
int find(node*tr,int nod,int l,int r,int x,int y)
{//查找x到y的值
	if(x<=l && r<=y)
	{
		return	tr[nod].a; 
	}
	pushdown(tr,nod);
	int mid=(l+r)/2;
	if(x<=mid)
		return	find(tr,lson,x,y);
	if(mid<y)
		return find(tr,rson,x,y);
}

void dfs1(int u)
{
	int i,j,e;
	vis[u]=cas;
	for(i=1; i<LOG; i++) rmq[u][i]=rmq[rmq[u][i-1]][i-1];
	son[u]=1;
	for(e=first[u]; e!=-1; e=next[e])
	if(vis[E[e]]<cas)
	{
		int v=E[e];
		dep[v]=dep[u]+1;
		rmq[v][0]=u;
		dfs1(v);
		son[u]+=son[v];
	}
}
void dfs2(int u,int h)//第二次dfs划分轻重边
{
	int i,j,e,v;
	vis[u]=cas;
	int now=-1,tp=0;
	for(e=first[u]; e!=-1; e=next[e])
	if(vis[E[e]]<cas && tp <son[E[e]])//找重边
	{
		tp=son[E[e]];
		now=E[e];
	}
	if(now==-1)//找到一条重边的节点,建立线段树
	{
		maketree(u,h);
		return ;
	}
	dfs2(now,h+1);//找下一条重边
	for(e=first[u];e!=-1 ; e=next[e])
	{
		v=E[e];
		if(vis[v]<cas && v!=now)
			dfs2(v,1);
	}
}
void split(int rt)//两次深搜进行重边划分
{
	tl=qtr;//头赋值
	cas++;
	dep[rt]=1;//根节点
	clr(rmq,0);
	dfs1(rt);
	cas++;
	dfs2(rt,1);
}
int lca(int a,int b)
{//算出a 和b的公共祖先
	int i,tp=dep[b]-dep[a];
	if(tp<0)
	{
		tp=-tp;
		swap(a,b);
	}
	for(i=0; i<LOG; i++)
	if(tp&(1<<i))	b=rmq[b][i];
	if(a==b)	return a;
	for(i=LOG; i>=0; i--)
	if(rmq[a][i]!=rmq[b][i])
	{
		a=rmq[a][i];
		b=rmq[b][i];
	}
	return rmq[a][0];
}
int main()
{
#ifndef ONLINE_JUDGE
	freopen("in","r",stdin);
	//freopen("out","w",stdout);
#endif
    int i,j,k,p;
	while(scanf("%d%d%d",&n,&m,&p)!=EOF)
	{
		for(i=1; i<=n; i++)
			nodeval[i]=rd();
		init();
		int x,y,z;
		for(i=0; i<m; i++)
		{
			x=rd(); y=rd();
			ins(x,y);
		}
		
		split(1);
		int fa;
		char ch[10];
		for(i=0; i<p; i++)
		{
			scanf("%s",ch);
			if(ch[0]=='Q')
			{
				x=rd();
				int fa=belong[x];
				int ans=find(head[fa],1,1,trsz[fa],pos[x],pos[x]);
				printf("%d\n",ans);
			}
			else
			{
				x=rd(); y=rd(); z=rd();
				if(ch[0]=='D')
					z=-z;
				fa=lca(x,y);
				int h1=getupdate(fa,x,z);
				int h2=getupdate(fa,y,z);
				if(h1==0 && h2==0)//都是非重边的情况
				{
				int tp=belong[fa];
			update(head[tp],1,1,trsz[tp],pos[fa],pos[fa],z);
				}
			}
		}
	}	
}
